<@pp.dropOutputFile/>
<#-- iterate table list-->
<#list doc.tables as table>

<#-- generate package name -->
<#assign package = doc.groupid?replace(".", "/")> 
<#assign package = package + "/" + doc.artifactid?replace(".", "/")>
<#assign package = package + "/" + table.moduleid?replace(".", "/")>
<#assign fileName = table.name?cap_first>
<#assign namespace = table.moduleid?cap_first + "/" + table.name?cap_first>
<#if doc.tablePrefix?? && (doc.tablePrefix?length > 0)>
<#assign prefix = doc.tablePrefix + "_">
<#else>
<#assign prefix = "">
</#if>
<@pp.changeOutputFile name="/main/java/" + package + "/action/" + fileName + "Action.java"/>
/*
 * File name : ${fileName}Action.java ${doc.date}
 * Copyright ${doc.copyright}. All rights reserved.
 */
package ${package?replace("/", ".")}.action;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.servlet.http.HttpServletResponse;

import blackstone.comm.CodeUtil;
import blackstone.comm.Outcome;
import blackstone.jxls.JXLSExportUtil;
import blackstone.jxls.JXLSImportUtil;
import blackstone.comm.ValidateUtil;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.opensymphony.xwork.ActionSupport;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.webwork.WebWorkStatics;
import ${package?replace("/", ".")}.domain.${fileName};
import ${package?replace("/", ".")}.service.${fileName}Service;
import com.xust.nm2016.access_control.service.AccessControl;
import com.xust.nm2016.access_control.service.AccessControlService;

/**
 * Class ${fileName}Action
 * ${fileName} action class.
 * @author ${doc.author}
 * @version ${doc.version}, ${doc.date}
 */
public class ${fileName}Action extends ActionSupport implements AccessControl{

	private static final long serialVersionUID = 1L;
	private static final String DT = "${prefix}${fileName?upper_case}";
	private Log log = LogFactoryImpl.getLog(${fileName}Action.class);
	
	private ${fileName}Service ${table.name?uncap_first}Service = null;
	private AccessControlService accessControlService = null;
	private Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
	
	Map<String, Object> output = null;
	Outcome ocChain = null;	// Parameter for chain action
	
	///////////////////////////Parameters for pagination
	private Integer rows = null;
	private Integer page = null;
	private Integer total = null;
	private Date start = null;
	private Date end = null;
	//////////////////////////Front page theme
	private String theme = "bootstrap";
	
	//////////////////////////Parameters for operations
	private List<String> items = null;	//for delete
	private String id = null;
	private ${fileName} obj = null;	//for add and update
	private List<${fileName}> objs = null;	//for add and update

	// Parameters for import data from excel file
	private File excel;
    private String excelContentType;  
    private String excelFileName;
    private static String importMapping = "${table.name}-jxls-schema.xml";
    private static String exportTemplate = "${table.name}-jxls-template.xls";
	
    public String doShowImport(){
    	
    	return SUCCESS;
    }
    
    public String doImportExcel(){
		String res = SUCCESS;
		log.info(excelFileName);
		Outcome oc = JXLSImportUtil.importExcel(excelFileName, excel, ${fileName}.class, importMapping);
		if(oc.success()){
			objs = oc.getData();
		}else{
			objs = null;
			res = INPUT;
		}

		oc.setMessage(getText(oc.getMsg()));
		ocChain = oc;
		
    	return res;
	}
	
	public String doImport(){
		Outcome oc = new Outcome(-1);
		List<Map<String, String>> errors = ValidateUtil.validateSet(objs, this.getClass(), "importData");
		if(ValidateUtil.success(errors)){
			oc = ${table.name?uncap_first}Service.createBatch(objs);
		}else{
			oc.setResult(-1);
			oc.setData(errors);
			oc.setMsg("import.batch.error");
			log.error("import.batch.error");
		}

		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
    	
    	return SUCCESS;
    }

	<#--
    /**
     * JXL2.4.2
     * @param items
     * @return
     */
    private String exportJXL(List<${table.name}> items, String excelTemp){
    	String file = "";
    	
		try{
	    	WritableWorkbook workbook = jxl.Workbook.createWorkbook(new File(excelTemp));
	    	if(null != workbook){
				WritableCellFormat timesBoldUnderline = null;
				WritableFont font = new WritableFont(WritableFont.ARIAL, 20,
						WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE,
						Colour.BLACK);
				timesBoldUnderline = new WritableCellFormat(font);
				timesBoldUnderline.setWrap(true);
				timesBoldUnderline.setAlignment(Alignment.CENTRE);
				timesBoldUnderline.setVerticalAlignment(VerticalAlignment.CENTRE);

				WritableCellFormat timesBoldUnderlineOther = null;
				WritableFont font1 = new WritableFont(WritableFont.ARIAL, 11,
						WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE,
						Colour.BLACK);
				timesBoldUnderlineOther = new WritableCellFormat(font1);

				timesBoldUnderlineOther.setWrap(true);
				timesBoldUnderlineOther.setAlignment(Alignment.CENTRE);
				timesBoldUnderlineOther.setBorder(jxl.format.Border.ALL,
						jxl.format.BorderLineStyle.THIN);
				timesBoldUnderlineOther
						.setVerticalAlignment(VerticalAlignment.CENTRE);
				WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 10);
				WritableFont tableFont = new WritableFont(WritableFont.ARIAL, 11,
						WritableFont.BOLD);
				WritableCellFormat wcf_tabletitle = new WritableCellFormat(
						tableFont);
				WritableFont dateFont = new WritableFont(WritableFont.ARIAL, 9,
						WritableFont.BOLD);
				wcf_tabletitle.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条
				wcf_tabletitle.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐
				wcf_tabletitle.setAlignment(Alignment.CENTRE); // 水平对齐
				wcf_tabletitle.setWrap(true); // 是否换行
				// 用于正文
				WritableCellFormat wcf_center = new WritableCellFormat(NormalFont);
				wcf_center.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条
				// wcf_center.setBackground(Colour.ICE_BLUE); //设置单元格背景色
				wcf_center.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐
				wcf_center.setAlignment(Alignment.CENTRE);
				wcf_center.setWrap(true); // 是否换行
				// 用于页脚及页眉
				WritableCellFormat wcf_yejiao = new WritableCellFormat(dateFont);
				wcf_yejiao.setBorder(Border.NONE, BorderLineStyle.THIN);
				wcf_yejiao.setVerticalAlignment(VerticalAlignment.CENTRE);
				wcf_yejiao.setAlignment(Alignment.CENTRE);
				wcf_yejiao.setWrap(true);
				
				WritableSheet sheet = workbook.createSheet("New Sheet", 0);
				//Header
				short rowIndex = 0;
				int colIndex = 0;
				
				Label label = null;
				<#list table.fields as field>
		    	label = new Label(colIndex++, rowIndex, "<#if field.comment??>${field.comment}<#else>${field.name}</#if>", wcf_tabletitle);
				sheet.addCell(label);
				</#list>
						
		    	WritableCellFormat floatFormat = new WritableCellFormat (NumberFormats.FLOAT); 
		    	WritableCellFormat integerFormat = new WritableCellFormat (NumberFormats.INTEGER); 
				for(${table.name} item : items){
					rowIndex++;
					colIndex = 0;
					
					<#list table.fields as field>
					label = new Label(colIndex++, rowIndex, "" + item.get${field.name?cap_first}(), wcf_center);
					sheet.addCell(label);
					</#list>
			    }
				
				workbook.write(); 
				workbook.close();
	    	}
		}catch(Exception e){
			log.error(e.getMessage());
			file = "";
		}
		
		return file;
    }
	-->
	
	<#--
    public String doExport(){
    	id = null;
		page = 1;
		rows = 10000;
		Outcome ocSize = ${table.name?uncap_first}Service.size(id);
		Outcome oc = ${table.name?uncap_first}Service.getPage(page, rows, id);
		oc.setMessage(getText(oc.getMsg()));
		if(ocSize.success()){
			oc.setTotal((Integer)ocSize.getData());
		}
		
		log.error(new Date());
		
		List<${table.name}> items = ${table.name?uncap_first}Service.getPage4Server(oc);
	-->	
		<#--
		/** JXL */
		/*
		String path = JXLSExportUtil.buildPath("/excel_temp/");
		String excelTemp = path + JXLSExportUtil.generateName(".xls");
		String file = exportJXL(items, excelTemp);
		*/
		-->
	<#--	
		/** JXLS */
		String path = JXLSExportUtil.buildPath("/excel_temp/");
		String excelTemp = path + JXLSExportUtil.generateName(".xls");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("objs", items);
		String templatePath = JXLSExportUtil.findMe(${table.name?cap_first}.class);
		String file = JXLSExportUtil.exportExcel(map, excelTemp, templatePath + exportTemplate);

		if(JXLSExportUtil.push(file, ActionContext.getContext())){
			return NONE;
		}
		
		oc.setMsg("download.error");
		oc.setData("");
		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
		log.error(new Date());
		return SUCCESS;
    }
	-->

	/**
	 * Insert new ${fileName} object.
	 * @param ${fileName?uncap_first} New object.
	 * @return The id of new object which represented by value field of Result object.
	 */
	public String doCreate(){
		CodeUtil.decode_gbk(obj);
		Outcome oc = ${table.name?uncap_first}Service.create(obj);
		oc.setMessage(getText(oc.getMsg()));

		output = oc.toMapLt();
		return SUCCESS;
	}

	/**
	 * Retrieve object by id.
	 * @param id Target id.
	 * @return Target object.
	 */
	public String doGet(){
		Outcome oc = ${table.name?uncap_first}Service.get(id);
		oc.setMessage(getText(oc.getMsg()));

		output = oc.toMapLt();
		return SUCCESS;
	}
	<#--
	public String doGetJSON(){
		output = new HashMap<String, Object>();
		output.put("object", ${table.name?uncap_first}Service.get(id));
		return SUCCESS;
	}
	-->
	/**
	 * Retrieve objects in specified page.
	 * @param page Page number.
	 * @param rows The number of rows.
	 * @param total The number of total rows.
	 * @return Target objects.
	 */
	public String doGetPage(){
		Outcome ocSize = ${table.name?uncap_first}Service.size(id, start, end);
		Outcome oc = ${table.name?uncap_first}Service.getPage(page, rows, id, start, end);
		oc.setMessage(getText(oc.getMsg()));
		if(ocSize.success()){
			oc.setTotal((Integer)ocSize.getData());
		}
		ocChain = oc;
		return SUCCESS;
	}

	public String doPage2Json(){
		log.info(ocChain.toMapLt());
		output = ocChain != null ? ocChain.toMapLt() : new HashMap<String, Object>();
		return SUCCESS;
	}

	public String doPage2JsonRaw(){
		log.info(ocChain.toMapLt());
		output = ocChain != null ? ocChain.toMapLt() : new HashMap<String, Object>();
		return SUCCESS;
	}

	public String doPage2Excel(){
		log.info(rows);
		List<${table.name?cap_first}> items = ocChain.getData();
		
		/** JXLS */
		String path = JXLSExportUtil.buildPath("/temp/");
		String excel_name = JXLSExportUtil.generateName(".xls");
		String excelTemp = path + excel_name;
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("objs", items);
		String templatePath = JXLSExportUtil.findMe(${table.name?cap_first}.class);
		String template = "/${table.name}-jxls-template.xls";
		String file = JXLSExportUtil.exportExcel(map, excelTemp, templatePath + template, null);
		
		Outcome oc = null;
		if(null != file){
			oc = new Outcome(0);
			oc.setMsg("export.success");
			oc.setData(excel_name);
			oc.setMessage(getText(oc.getMsg()));
		}else{
			oc = new Outcome(-1);
			oc.setMsg("export.fail");
			oc.setData(excel_name);
			oc.setMessage(getText(oc.getMsg()));
		}
		
		output = oc.toMapLt();
		log.error(new Date());

		return SUCCESS;
	}
    
    private boolean push2Client(String xls){
    	boolean res = false;
    	try{
        	File file = new File(xls);
        	String fileName = file.getName();
	    	InputStream input = new FileInputStream(file);  
	  
	        int nSize = input.available();  
	        byte[] byteArray = new byte[nSize];  
	        input.read(byteArray);  
	        input.close();  
	        fileName = new String(fileName.getBytes("GBK"), "iso8859-1");
	        
	        ActionContext ctx = ActionContext.getContext();
	        HttpServletResponse response = (HttpServletResponse)ctx.get(WebWorkStatics.HTTP_RESPONSE);
	        response.reset();  
	        response.setContentType("application/vnd.ms-excel");  
	        response.setHeader("Content-disposition", "attachment; filename=" + fileName);  
	        OutputStream outFile = response.getOutputStream();  
	        outFile.write(byteArray);  
	        outFile.flush();  
	        outFile.close();
	        res = true;
    	}catch(Exception e){
    		log.error(e.getMessage());
    	}
    	
    	return res;
    }
	<#--
	public String doGetPageJSON(){
		output = new HashMap<String, Object>();
		total = ${table.name?uncap_first}Service.size();
		Page pi = new Page(page, rows, total);
		output.put("data", ${table.name?uncap_first}Service.getPage(pi));
		return SUCCESS;
	}
	-->
	/**
	 * Retrieve all objects.
	 * @return Target objects.
	 */
	public String doGetAll(){
		Outcome oc = ${table.name?uncap_first}Service.getAll();
		oc.setMessage(getText(oc.getMsg()));

		output = oc.toMapLt();
		return SUCCESS;
	}
	<#--
	public String doGetAllJSON(){
		output = new HashMap<String, Object>();
		output.put("data", ${table.name?uncap_first}Service.getAll());
		return SUCCESS;
	}
	-->
	
	public String doEdit(){
		CodeUtil.decode_gbk(obj);
		Outcome oc = ${table.name?uncap_first}Service.update(obj);
		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
		return SUCCESS;
	}
	
	public void validateDoUpdate(){
		if(isLocked(obj.get${table.idFieldName?cap_first}())){
			log.info("Expired!");
			addActionError(getText("update.expired"));
		}
	}
	
	/**
	 * Update new ${fileName} object.
	 * @param ${fileName?uncap_first} New object.
	 * @return The id of new object which represented by value field of Result object.
	 */
	public String doUpdate(){
		return SUCCESS;
	}

	public void validateDoDelete(){
		if(isLocked(id)){
			log.info("Expired!");
			addActionError(getText("delete.expired"));
		}
	}
	/**
	 * Delete objects which id were included in items array.
	 * @param items Target ids.
	 * @return The number of rows affected which represented by value field of Result object.
	 */
	public String doDelete(){
		Outcome oc = ${table.name?uncap_first}Service.delete(id);
		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
		return SUCCESS;
	}

	public String doShowCheck(){
		return SUCCESS;
	}
	
	public String doReset(){
		Outcome oc = unlock(new ArrayList<Object>(items));
		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
		return SUCCESS;
	}

	public void validateDoDeleteItems(){
		for(String id : items){
			if(isLocked(id)){
				log.info("Expired!");
				addActionError(getText("delete.expired"));
				break;
			}
		}
	}
	/**
	 * Delete objects which id were included in items array.
	 * @param items Target ids.
	 * @return The number of rows affected which represented by value field of Result object.
	 */
	public String doDeleteItems(){
		Outcome oc = ${table.name?uncap_first}Service.deleteItems(items);
		oc.setMessage(getText(oc.getMsg()));
		
		output = oc.toMapLt();
		return SUCCESS;
	}

	/**
	 * Request ${fileName} object data view.
	 * @return ${fileName} object data view.
	 */
	public String doShowItems(){
		return SUCCESS;
	}
	
	<#list table.apis as api>
	<#if (api.name != "update") && (api.name != "findPageData") && (api.name != "deleteItems") && (api.name != "add") && (api.name != "showItems")>
	/**
	 * <#if api.comment?exists>${api.comment}</#if>.
	 <#list api.params as param>
	 * @param ${param.name} ${param.type}.
	 </#list>
	 * @return <#if api.return?exists>${api.return}</#if>.
	 */
	public String do${api.name?cap_first}(){
		output = new HashMap<String, Object>();
		output.put("object","OK");
		return SUCCESS;
	}	
	</#if>
	</#list>
	
	public Map<String, Object> getOutput() {
		return output;
	}

	public void setOutput(Map<String, Object> output) {
		this.output = output;
	}

	public Integer getRows() {
		return rows;
	}

	public void setRows(Integer rows) {
		this.rows = rows;
	}

	public Integer getPage() {
		return page;
	}

	public void setPage(Integer page) {
		this.page = page;
	}

	public Integer getTotal() {
		return total;
	}

	public void setTotal(Integer total) {
		this.total = total;
	}

	public String getTheme() {
		return theme;
	}

	public void setTheme(String theme) {
		this.theme = theme;
	}
	
	public List<String> getItems() {
		return items;
	}

	public void setItems(List<String> items) {
		this.items = items;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public File getExcel() {
		return excel;
	}

	public void setExcel(File excel) {
		this.excel = excel;
	}

	public String getExcelContentType() {
		return excelContentType;
	}

	public void setExcelContentType(String excelContentType) {
		this.excelContentType = excelContentType;
	}

	public String getExcelFileName() {
		return excelFileName;
	}

	public void setExcelFileName(String excelFileName) {
		this.excelFileName = excelFileName;
	}

	public ${table.name?cap_first}Service get${table.name?cap_first}Service() {
		return ${table.name?uncap_first}Service;
	}

	public void set${table.name?cap_first}Service(${table.name?cap_first}Service ${table.name?uncap_first}Service) {
		this.${table.name?uncap_first}Service = ${table.name?uncap_first}Service;
	}

	public ${fileName} getObj() {
		return obj;
	}

	public void setObj(${fileName} o) {
		this.obj = o;
	}

	public List<${fileName}> getObjs() {
		return objs;
	}

	public void setObjs(List<${fileName}> o) {
		this.objs = o;
	}

	public Outcome getOcChain() {
		return ocChain;
	}

	public void setOcChain(Outcome ocChain) {
		this.ocChain = ocChain;
	}

	public Date getStart() {
		return start;
	}

	public void setStart(Date o) {
		this.start = o;
	}
	public Date getEnd() {
		return end;
	}

	public void setEnd(Date o) {
		this.end = o;
	}
	
	public boolean isLocked(Object id) {
		return accessControlService.isLocked(id, DT);
	}

	public Outcome lock() {
		return accessControlService.lock(DT);
	}

	public Outcome locks(List<Object> ids) {
		return accessControlService.locks(ids, DT);
	}

	public Outcome unlock(List<Object> ids) {
		return accessControlService.unlock(null, ids, DT);
	}

	public AccessControlService getAccessControlService() {
		return accessControlService;
	}

	public void setAccessControlService(AccessControlService accessControlService) {
		this.accessControlService = accessControlService;
	}

}
</#list>